﻿namespace SLRiaServicesEx
{
    using System.Collections.Generic;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using System.Windows;
    using System;
    using System.Reflection;
    using System.Linq;
    using SLNavigationFrameworkEx;

    public static partial class DomainDataSourceHelper
    {
        #region Public Methods

        #region Public Method ClearFilters

        public static void ClearFilters(this DomainDataSource dds)
        {
            if (dds.CanLoad)
            {
                dds.FilterDescriptors.Clear();
            }
        }

        #endregion

        #region Public Method AddFilter

        public static void AddFilter(this DomainDataSource dds, string property, FilterOperator filterOperator, object value)
        {
            if (!string.IsNullOrEmpty(property) && !string.IsNullOrEmpty(value.ToString()))
            {
                dds.FilterDescriptors.Add(new FilterDescriptor() { PropertyPath = property, Operator = filterOperator, Value = value });
            }
        }

        #endregion

        #region Public Method ClearQueryParams

        public static void ClearQueryParams(this DomainDataSource dds)
        {
            if (dds.CanLoad)
            {
                dds.QueryParameters.Clear();
            }
        }

        #endregion

        #region Public Method AddQueryParam

        public static void AddQueryParam(this DomainDataSource dds, string fieldName, object fieldValue)
        {
            if (dds.CanLoad)
            {
                dds.QueryParameters.Add(new Parameter() { ParameterName = fieldName, Value = fieldValue });
            }
        }

        #endregion

        #region Public Method LoadDDS

        public static void LoadDDS(this DomainDataSource dds)
        {
            if (dds.CanLoad)
            {
                dds.Load();
            }
        }

        #endregion

        #region Public Method SubmitChangesAndGoBack

        public static void SubmitChangesAndGoBack(this DomainDataSource dds, NavigationService ns)
        {
            if (dds.HasChanges)
            {
                dds.SubmittedChanges += (ss, ee) =>
                {
                    ns.ShowPrevPage();
                };

                dds.SubmitChanges();
            }
        }

        #endregion

        #region Public Method RejectChangesAndGoBack

        public static void RejectChangesAndGoBack(this DomainDataSource dds, NavigationService ns)
        {
            if (dds.HasChanges)
            {
                dds.RejectChanges();
            }
            ns.ShowPrevPage();
        }

        #endregion

        #region Public Method LoadDDSByNavigationContext

        public static void LoadDDSByNavigationContext(this DomainDataSource dds, NavigationContext nc)
        {
            dds.ClearQueryParams();

            foreach (var paramName in GetDDSQueryParams(dds))
            {
                if (nc.IsParamKeyExists(paramName))
                {
                    dds.AddQueryParam(paramName, nc.GetParamAsInt(paramName));
                }
            }

            dds.LoadDDS();
        }

        #endregion

        #region Public Method LoadDDSByValueParams

        public static void LoadDDSByValueParams(this DomainDataSource dds, List<object> valueList)
        {
            dds.ClearQueryParams();

            var paramList = GetDDSQueryParams(dds);

            if (paramList.Count == valueList.Count)
            {
                foreach (var paramName in paramList)
                {
                    int index = paramList.IndexOf(paramName);
                    dds.AddQueryParam(paramName, valueList[index]);
                }
            }

            dds.LoadDDS();
        }

        #endregion

        #region Public Method GetDDSQueryParams

        public static IList<string> GetDDSQueryParams(this DomainDataSource dds)
        {
            List<string> result = new List<string>();

            Type domainContextType = dds.DomainContext.GetType();

            if (domainContextType == null)
            {
                return result;
            }

            string queryName = dds.QueryName;

            if (!queryName.Contains("Query"))
            {
                queryName += "Query";
            }

            MethodInfo operationInfo = domainContextType.GetMethods().Where(m => m.Name == queryName).FirstOrDefault();

            if (operationInfo == null)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("Could not find a method named {0}.", queryName));
            }
            else
            {
                foreach (var item in operationInfo.GetParameters())
                {
                    result.Add(item.Name);
                }
            }

            return result;
        }

        #endregion

        #endregion
    }
}
